package com.github.live.component;

import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.github.live.R;
import com.github.live.adapter.LiveSettingAdapter;
import com.github.live.adapter.LiveSettingItem;
import com.github.live.manager.ChannelsManager;
import com.github.live.base.VisibleComponent;
import com.github.live.manager.LiveInitializer;
import com.github.livebase.bean.Channel;
import com.github.live.manager.SettingManager;
import com.github.live.util.store.HawkConfig;
import com.github.livebase.util.function.Callback;
import com.owen.tvrecyclerview.widget.TvRecyclerView;
import com.owen.tvrecyclerview.widget.V7LinearLayoutManager;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.github.livebase.util.base.*;

/**
 * @ClassName LiveSettingView
 * @description:
 * @author: biao532
 * @create: 2023-12-08 13:23
 * @Version 1.0
 **/
public class LiveSettingView extends LinearLayout implements VisibleComponent {
    public interface SettingListener {
        SettingListener Empty = new SettingListener() {
            @Override
            public void onSourceChange(int sourceIndex) {

            }

            @Override
            public void onScaleChange(int index) {

            }

            @Override
            public void onPlayerChange(int index) {

            }

            @Override
            public void onTimeShowChange() {

            }

            @Override
            public void onNetSpeedShowChange() {

            }
        };
        void onSourceChange(int sourceIndex);
        void onScaleChange(int index);
        void onPlayerChange(int index);
        void onTimeShowChange();
        void onNetSpeedShowChange();
    }
    private List<LiveSettingItem> liveSettingGroupList = new ArrayList<>();
    private LiveSettingAdapter liveSettingGroupAdapter;
    private LiveSettingAdapter liveSettingItemAdapter;
    private TvRecyclerView mSettingItemView;
    private TvRecyclerView mSettingGroupView;
    private SettingListener listener = SettingListener.Empty;
    private SettingManager setting;
    private Handler mHandler;
    private Channel channelItem;
    private LiveInitializer initializer;
    private WeakReference<LiveSettingView> _this = new WeakReference<>(this);
    private Runnable mHideSettingLayoutRun = () -> {
        LiveSettingView __this = _this.get();
        if (__this == null) {
            return;
        }
        if (__this.getVisibility() == View.VISIBLE) {
            __this.setVisibility(View.GONE);
        }
    };

    public void setChannel(Channel newChannel) {
        channelItem = newChannel;
        LiveSettingItem sources = liveSettingGroupList.get(0);
        List<LiveSettingItem> items = CollectionsUtil.convert(newChannel.getSources(), (s) -> new LiveSettingItem(s.getName()));
        sources.setChildren(items);
    }

    public LiveSettingView(Context context) {
        super(context);
        init(context);
    }

    public LiveSettingView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }
    public void setListener(SettingListener listener) {
        this.listener = listener==null?SettingListener.Empty:listener;
    }

    public void setHandler(Handler mHandler) {
        this.mHandler = mHandler;
    }

    private void selectSettingGroup(int position) {
        if (position != 0 && (position == liveSettingGroupAdapter.getSelectedIndex() || position < -1))
            return;
        liveSettingGroupAdapter.setSelectedIndex(position);
        liveSettingItemAdapter.setData(liveSettingGroupList.get(position).getChildren());
        ChannelsManager c = LiveInitializer.getInitializer().getChannelsManager();
        switch (position) {
            case 0:
                liveSettingItemAdapter.setSingleActiveIndex(c.getCurrentSourceIndex());
                break;
            case 1:
                liveSettingItemAdapter.setSingleActiveIndex(setting.getScaleNameIndex(c.getCurrentSource()));
                break;
            case 2:
                liveSettingItemAdapter.setSingleActiveIndex(setting.getPlayerNameIndex(c.getCurrentSource()));
                break;
            case 3:
                liveSettingItemAdapter.setSingleActiveIndex(setting.getTimeoutIndex());
                break;
            case 5:
                liveSettingItemAdapter.setSingleActiveIndex(setting.getRenderNameIndex(c.getCurrentSource()));
                break;
        }
        int scrollToPosition = liveSettingItemAdapter.getSelectedIndex();
        if (scrollToPosition < 0) scrollToPosition = 0;
        mSettingItemView.scrollToPosition(scrollToPosition);
        hide(initializer.getConfig().getSettingWaitfor());
    }

    private void clickSettingItem(int position) {
        int settingGroupIndex = liveSettingGroupAdapter.getSelectedIndex();
        ChannelsManager c = LiveInitializer.getInitializer().getChannelsManager();
        switch (settingGroupIndex) {
            case 0://线路切换
                listener.onSourceChange(position);
                c.setCurrentChannelSource(position);
                liveSettingItemAdapter.setSingleActiveIndex(position);
                break;
            case 1://画面比例
                setting.resetScale(position);
                setting.setScaleNameIndex(c.getCurrentSource(), position);
                listener.onScaleChange(position);
                liveSettingItemAdapter.setSingleActiveIndex(position);
                break;
            case 2://播放解码
                setting.setPlayerNameIndex(c.getCurrentSource(), position);
                setting.resetPlayer(position);
                liveSettingItemAdapter.setSingleActiveIndex(position);
                listener.onPlayerChange(position);
                break;
            case 3://超时换源
                liveSettingItemAdapter.setSingleActiveIndex(position);
                setting.setTimeoutIndex(position);
                break;
            case 4://偏好设置
                boolean select = false;
                String[] keys = new String[]{HawkConfig.LIVE_SHOW_TIME, HawkConfig.LIVE_SHOW_NET_SPEED, HawkConfig.LIVE_CHANNEL_REVERSE};
                Callback.VoidCallback[] voids = new Callback.VoidCallback[]{listener::onTimeShowChange, listener::onNetSpeedShowChange, ()->{}};
                if (position < keys.length) {
                    select = !setting.getSettingAttr(keys[position], false);
                    setting.setSettingAttr(keys[position], select);
                    voids[position].accept();
                }
                liveSettingItemAdapter.setMultiActiveIndex(position, select);
                break;
            case 5: // 渲染容器
                setting.setRenderNameIndex(c.getCurrentSource(), position);
                setting.resetRenderFactory(position);
                liveSettingItemAdapter.setSingleActiveIndex(position);
                break;
        }
        hide(initializer.getConfig().getSettingWaitfor());
    }

    @Override
    public void show() {
        if (isShowing()) {
            return;
        }
        if (channelItem != null) {
            selectSettingGroup(0);
            mSettingGroupView.scrollToPosition(0);
        }
        RecyclerView.ViewHolder holder = mSettingGroupView.findViewHolderForAdapterPosition(0);
        if (holder != null)
            holder.itemView.requestFocus();
        setVisibility(View.VISIBLE);
        hide(initializer.getConfig().getSettingWaitfor());
    }

    @Override
    public void hide(long delay) {
        mHandler.removeCallbacks(mHideSettingLayoutRun);
        mHandler.postDelayed(mHideSettingLayoutRun, delay);
    }

    private void init(Context context) {
        initializer = LiveInitializer.getInitializer();
        setting = initializer.getSettingManager();
        LayoutInflater.from(context).inflate(R.layout.component_liveplay_setting, this);
        mSettingGroupView = findViewById(R.id.mSettingGroupView);
        mSettingItemView = findViewById(R.id.mSettingItemView);

        initLiveSettingGroupList();
        initSettingGroupView();
        initSettingItemView();
    }
    private void initSettingGroupView() {
        mSettingGroupView.setHasFixedSize(true);
        mSettingGroupView.setLayoutManager(new V7LinearLayoutManager(getContext(), 1, false));

        liveSettingGroupAdapter = new LiveSettingAdapter();
        mSettingGroupView.setAdapter(liveSettingGroupAdapter);
        liveSettingGroupAdapter.setData(liveSettingGroupList);
        mSettingGroupView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                hide(initializer.getConfig().getSettingWaitfor());
            }
        });

        //电视
        mSettingGroupView.setOnItemListener(new TvRecyclerView.OnItemListener() {
            @Override
            public void onItemPreSelected(TvRecyclerView parent, View itemView, int position) {
            }

            @Override
            public void onItemSelected(TvRecyclerView parent, View itemView, int position) {
                selectSettingGroup(position);
            }

            @Override
            public void onItemClick(TvRecyclerView parent, View itemView, int position) {
            }
        });

    }
    private void initSettingItemView() {
        mSettingItemView.setHasFixedSize(true);
        mSettingItemView.setLayoutManager(new V7LinearLayoutManager(getContext(), 1, false));

        liveSettingItemAdapter = new LiveSettingAdapter();
        mSettingItemView.setAdapter(liveSettingItemAdapter);
        mSettingItemView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                hide(initializer.getConfig().getSettingWaitfor());
            }
        });

        //电视
        mSettingItemView.setOnItemListener(new TvRecyclerView.OnItemListener() {
            @Override
            public void onItemPreSelected(TvRecyclerView parent, View itemView, int position) {
            }

            @Override
            public void onItemSelected(TvRecyclerView parent, View itemView, int position) {
                if (position < 0) return;
                //liveSettingGroupAdapter.setFocusedGroupIndex(-1);
                //liveSettingItemAdapter.setFocusedItemIndex(position);
                hide(initializer.getConfig().getSettingWaitfor());
            }

            @Override
            public void onItemClick(TvRecyclerView parent, View itemView, int position) {
                clickSettingItem(position);
            }
        });
    }
    private void initLiveSettingGroupList() {
        List<String> groupNames = Arrays.asList(setting.groupNames());

        List<List<String>> settingNames = Arrays.asList(
                // 线路选择,空列表
                new ArrayList<>(),
                // 画面比例
                Arrays.asList(setting.scaleNames()),
                // 播放解码
                setting.playerNames(),
                // 超时换源
                Arrays.asList(setting.timeoutNames()),
                // 偏好设置
                Arrays.asList(setting.preferenceName()),

                Arrays.asList(setting.renderNames())
        );

        // 将name转换成LiveSettingGroup
        List<LiveSettingItem> groups = CollectionsUtil.convert(groupNames, LiveSettingItem::new);

        // 设置LiveSettingGroup的 items;
        CollectionsUtil.foreach(groups, (i, g) -> {
            List<LiveSettingItem> c = CollectionsUtil.convert(settingNames.get(i), LiveSettingItem::new);
            g.setChildren(c);
        });

        // 设置偏好选项的默认值
        final String[] keys = new String[]{HawkConfig.LIVE_SHOW_TIME, HawkConfig.LIVE_SHOW_NET_SPEED, HawkConfig.LIVE_CHANNEL_REVERSE};
        CollectionsUtil.foreach(groups.get(4).getChildren(), (i, s) -> {
            s.setSelected(setting.getSettingAttr(keys[i], false));
        });

        liveSettingGroupList = groups;
    }
}
